﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FanaticToy.Core.Utils
{
    ///<summary>方法的 MetaUtils</summary>
    public static class ClassMetaUtils
    {
        ///<summary>方法有时候一定会用这些关键词来修饰。</summary>
        private static readonly string[] ClassNeedKeywords = new string[]
        {
            "class"
        };


        ///<summary>方法有时候一定会用这些关键词来修饰。</summary>
        private static readonly string[] ClassKeywords = new string[]
        {
            "internal", "public", 
            "static", "abstract", ":",
        };

        ///<summary>定义方法时绝对不会包括的一些关键词。</summary>
        private static readonly string[] ClassNotInclude = new string[]
        {
            "=>", ",", "private","protected", "new", "var", "struct",
            "record", "=","return",
            "if","for","while","do","foreach","switch","case", "event"
        };

        public static bool TryGetMethodName(string codeLine, out string classId)
        {
            classId = string.Empty;
            if (string.IsNullOrWhiteSpace(codeLine)) return false;
            if (codeLine.Contains(';')) return false;
            var hasId = HasId(codeLine, out classId);
          
            return hasId;
        }

        ///<summary>是否具有特定标识符的ID.</summary>
        private static bool HasId(in string codeLine, out string classId)
        {
            classId = string.Empty;
      
            if(string.IsNullOrWhiteSpace(codeLine))  return false;

            var splitedCodeLineRaw = codeLine;
            var splitedCodeLineRawParts = splitedCodeLineRaw.Split();

            if (splitedCodeLineRawParts.Length < 2) return false;
            if (splitedCodeLineRawParts.Last().StartsWith(".")) return false;

            foreach (string notInclude in ClassNotInclude)
            {
                if (splitedCodeLineRaw.Contains(notInclude)) return false;
            }

            foreach (string needInclude in ClassNeedKeywords)
            {
                if (!splitedCodeLineRaw.Contains(needInclude)) return false;
            }

            classId = splitedCodeLineRawParts.Last();

            return true;
        }

        public static string GetClassId(string filePath)
        {
            using (var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
            {
                var list = new List<string>();
                using (var sr = new StreamReader(fs))
                {
                    while (true)
                    {
                        var line = sr.ReadLine();
                        if (line == null) break;
                        if (TryGetMethodName(line, out var classId))
                        {
                            return classId;
                        }
                    }

                }
            }
            return string.Empty;
        }

    }
}
